/**
* @brief 菜单系统实现
* 实现各状态菜单的界面和用户交互逻辑
*/
#include "menu.h"
#include "comm.h"
#include "dlist.h"
#include "device.h"


//辅助函数，提示用户按任意键继续
static void press_any_key() {
	printf("按任意键继续\n");
	CLEAR_BUFFER();// 清空输入缓冲区
	getchar();// 等待用户按键
}


/**
 * @brief 欢迎界面菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState welcome_menu(node_t * devlist) 
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	char select;
	while(1)
	{
		system("clear");// 清屏
		printf("欢迎使用智能家居设备管理系统\n");
		printf("请输入您的选择：\n");
		printf("1:用户登录\n");
		printf("q:退出系统\n");
		scanf(" %c",&select);
		if(select == '1')
		{
			return LOGIN_STATE;
		}
		else if(select == 'q')
		{
			return EXIT_STATE;
		}
		else
			printf("输入有误，请重试\n");
		press_any_key();
	}
	return WELCOME_STATE;
}


/**
 * @brief 登录界面菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState login_menu(node_t * devlist) 
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	char username[16] = "";
	char password[16] = "";

	int i = 0;
	// 允许最多LOOPCOUNT次尝试
	while(i < LOOPCOUNT)
	{
		system("clear");
		printf("请输入您的用户名:\n");
		scanf("%s",username);
		printf("请输入您的密码:\n");
		scanf("%s",password);
		// 验证管理员凭证
		if(!strcmp(username,ADMIN_NAME) && !strcmp(password,ADMIN_PASS))
		{
			return ADMIN_STATE;// 验证成功
		}
		else
			i++;// 增加尝试计数
		printf("输入有误，请重试\n");
		printf("您还有%d次机会\n",LOOPCOUNT-i);
		press_any_key();
	}
	return EXIT_STATE;// 超过尝试次数退出
}


/**
 * @brief 管理主菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState admin_menu(node_t * devlist) 
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	char select;
	while(1)
	{
		system("clear");
		printf("欢迎进入管理菜单,请选择：\n");
		printf("1:添加设备\n");
		printf("2:删除设备\n");
		printf("3:修改设备\n");
		printf("4:显示设备\n");
		printf("5:查找设备\n");
		printf("0:返回登录界面\n");
		printf("q:退出系统\n");
		scanf(" %c",&select);
		switch(select)
		{
		case '1':
			return ADD_STATE;
		case '2':
			return DEL_STATE;
		case '3':
			return UPDATE_STATE;
		case '4':
			return SHOW_STATE;
		case '5':
			return FIND_STATE;
		case '0':
			return LOGIN_STATE;
		case 'q':
			return EXIT_STATE;
		default:
			printf("输入有误，请重试\n");
			press_any_key();
			break;
		}
	}
	return 0;
}


/**
 * @brief 添加设备菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState add_dev_menu(node_t *devlist) 
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	device_t *newdev = malloc(sizeof(device_t));
	if(NULL == newdev)
		return ADMIN_STATE;
	newdev->dev_id = generate_id();// 生成唯一ID
	while(1)
	{
		system("clear");
		printf("欢迎进入添加设备菜单\n");
		printf("新设备ID: %d (系统自动生成)\n", newdev->dev_id);
		// 收集设备信息
		printf("请输入新设备序号:\n");
		scanf("%d",&(newdev->dev_order));
		printf("请输入新设备工作状态(1:ON 0:OFF):\n");
		CLEAR_BUFFER();
		scanf("%c", &(newdev->dev_status));
		printf("请输入新设备当前值:\n");
		scanf("%f",&(newdev->cur_value));
		printf("请输入新设备名:\n");
		scanf("%s",newdev->dev_name);
		printf("请输入新设备类型:\n");
		scanf("%s",newdev->dev_type);
		printf("请输入新设备IPV4:\n");
		scanf("%s",newdev->dev_ip);
		printf("请输入新设备额定功率:\n");
		scanf("%f",&(newdev->power_ele));
		// 添加设备到链表
		int res = add_dev(devlist,newdev);
		free(newdev);
		show_hdlist(devlist,showfun_dev_full);// 显示当前设备列表
		if(res == 0)
			break;
		printf("输入有误，请重试");
		press_any_key();
		return ADD_STATE;
	}
	printf("添加成功\n");
	press_any_key();
	return ADMIN_STATE;
}


/**
 * @brief 删除设备菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState del_dev_menu(node_t *devlist)
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	int select,res = 1;
	device_t *dev = malloc(sizeof(device_t));
	while(1)
	{
		system("clear");
		printf("欢迎进入删除设备菜单，请选择:\n");
		printf("1:按编号删除设备\n");
		printf("2:按设备名删除设备\n");
		printf("3:按设备类型删除设备\n");
		printf("0:返回管理菜单\n");
		scanf("%d",&select);
		switch(select)
		{
		case 1:// 按ID删除
			printf("请输入设备编号:\n");
			scanf("%d",&(dev->dev_id));
			res = del_dev(devlist,1,dev);
			if(res == 0)
			{
				printf("删除成功!\n");
				press_any_key();
				free(dev);
				return ADMIN_STATE;
			}
			break;
		case 2:// 按名称删除
			printf("请输入设备名:\n");
			scanf("%s",dev->dev_name);
			res = del_dev(devlist,2,dev);
			if(res == 0)
			{
				printf("删除成功!\n");
				press_any_key();
				free(dev);
				return ADMIN_STATE;
			}
			break;
		case 3:// 按类型删除
			printf("请输入设备类型:\n");
			scanf("%s",dev->dev_type);
			res = del_dev(devlist,3,dev);
			if(res == 0)
			{
				printf("删除成功!\n");
				press_any_key();
				free(dev);
				return ADMIN_STATE;
			}
			break;
		case 0:// 返回主菜单
			free(dev);
			return ADMIN_STATE;
		default:
			free(dev);
			printf("输入有误，请重试\n");
			press_any_key();
			return DEL_STATE;
		}
		printf("设备不存在\n");
		press_any_key();
		return DEL_STATE;
	}
	return ADMIN_STATE;
}


/**
 * @brief 更新设备菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState update_dev_menu(node_t * devlist)
{
	SYSERR(NULL,==,devlist,"dev is null",-1);
	int select,flag = 1;
	device_t *updatedev = malloc(sizeof(device_t));
	node_t *temp;
	while(1)
	{
		system("clear");
		printf("欢迎进入修改设备菜单\n");
		printf("请选择需要修改的设备属性\n");
		printf("1:修改设备名\n");
		printf("2:修改设备类型\n");
		printf("3:修改设备IP\n");
		printf("0:返回管理菜单\n");
		scanf("%d",&select);
		switch(select)
		{
		case 1:// 修改名称
			printf("请输入需要修改的设备的设备号:\n");
			scanf("%d",&updatedev->dev_id);
			temp = find_dev(devlist,1,updatedev);// 按ID查找
			if(temp == NULL)
				printf("设备不存在，请重试\n");
			else
			{
				// 检查是否重复
				printf("原设备名:%s\n",((device_t *)temp->data)->dev_name);
				printf("请输入新的设备名:\n");
				scanf("%s",updatedev->dev_name);
				if(!strcmp(updatedev->dev_name,((device_t *)temp->data)->dev_name))
					printf("新设备名与原设备名相同，修改失败\n");
				else
				{
					temp = update_dev(devlist,updatedev->dev_id,updatefun_dev_name,updatedev);
					printf("修改成功\n");
				}
			}
			press_any_key();
			free(updatedev);
			break;
		case 2:// 修改类型
			printf("请输入需要修改的设备的设备号:\n");
			scanf("%d",&updatedev->dev_id);
			temp = find_dev(devlist,1,updatedev);
			if(temp == NULL)
				printf("设备不存在，请重试\n");
			else
			{
				printf("原设备类型:%s\n",((device_t *)temp->data)->dev_type);
				printf("请输入新的设备类型:\n");
				scanf("%s",updatedev->dev_type);
				if(!strcmp(updatedev->dev_type,((device_t *)temp->data)->dev_type))
					printf("新设备类型与原设备类型相同，修改失败\n");
				else
				{
					temp = update_dev(devlist,updatedev->dev_id,updatefun_dev_type,updatedev);
					printf("修改成功\n");
				}
			}
			press_any_key();
			free(updatedev);
			break;
		case 3:// 修改IP
			printf("请输入需要修改的设备的设备号:\n");
			scanf("%d",&updatedev->dev_id);
			temp = find_dev(devlist,1,updatedev);
			if(temp == NULL)
				printf("设备不存在，请重试\n");
			else
			{
				printf("原设备IP:%s\n",((device_t *)temp->data)->dev_ip);
				printf("请输入新的设备IP:\n");
				scanf("%s",updatedev->dev_ip);
				if(!strcmp(updatedev->dev_ip,((device_t *)temp->data)->dev_ip))
					printf("新设备IP与原设备IP相同，修改失败\n");
				else
				{
					temp = update_dev(devlist,updatedev->dev_id,updatefun_dev_ip,updatedev);
					printf("修改成功\n");
				}
			}
			press_any_key();
			free(updatedev);
			break;
		case 0:
			free(updatedev);
			return ADMIN_STATE;
		default:
			flag = 0;
			printf("输入有误，请重试\n");
			press_any_key();
			free(updatedev);
			return UPDATE_STATE;
		}
		if(flag)
			break;
		// 显示更新后的设备信息
		show_dev(temp,showfun_dev_full);
		press_any_key();
		break;
	}
	return UPDATE_STATE;
}


/**
 * @brief 显示设备菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState show_dev_menu(node_t * devlist) 
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	int select,flag = 1;
	while(1)
	{
		system("clear");
		printf("欢迎进入显示设备菜单\n");
		printf("请输入您的选择\n");
		printf("1:根据设备号升序排列\n");
		printf("2:根据设备名称升序排列\n");
		printf("3:根据设备类型升序排列\n");
		printf("0:返回到管理菜单\n");
		scanf("%d",&select);
		switch(select)
		{
		case 1:// 按ID排序显示
			if(!(sort_dev(devlist,cmpfun_dev_id)))
			{
				set_device_order(devlist); 
				show_hdlist(devlist,showfun_dev_full);
			}
			press_any_key();
			return ADMIN_STATE;
		case 2:// 按名称排序显示
			if(!(sort_dev(devlist,cmpfun_dev_name)))
			{
				set_device_order(devlist); 
				show_hdlist(devlist,showfun_dev_full);
			}
			press_any_key();
			return ADMIN_STATE;
		case 3:// 按类型排序显示
			if(!(sort_dev(devlist,cmpfun_dev_type)))
			{
				set_device_order(devlist); 
				show_hdlist(devlist,showfun_dev_full);
			}
			press_any_key();
			return SHOW_STATE;
		case 0:
			return ADMIN_STATE;
		default :
			flag = 0;
			printf("输入有误，请重试\n");
			press_any_key();
			return SHOW_STATE;
		}
		if(flag)
			break;
		press_any_key();
	}
	return SHOW_STATE;

}


/**
 * @brief 查找设备菜单
 * 
 * @param devlist 设备链表指针
 * @return MenuState 下一状态
 */
MenuState find_dev_menu(node_t * devlist)
{
	SYSERR(NULL,==,devlist,"devlist is null",-1);
	int select;
	device_t dev;// 临时存储查找条件
	while(1)
	{
		system("clear");
		printf("欢迎进入查找设备菜单\n");
		printf("请输入您的选择\n");
		printf("1:根据设备号查找\n");
		printf("2:根据设备名查找\n");
		printf("3:根据设备类型查找\n");
		printf("0:返回到管理菜单\n");
		scanf("%d",&select);
		switch(select)
		{
		case 1:// 按ID查找
			printf("请输入设备号\n");
			scanf("%d",&(dev.dev_id));
			node_t *res1 = find_dev(devlist,1,&dev);
			if(res1 != NULL)
				show_dev(res1,showfun_dev_full);
			else
				printf("未找到设备\n");
			press_any_key();
			break;
		case 2:// 按名称查找
			printf("请输入设备名称\n");
			scanf("%s",dev.dev_name);
			node_t *res2 = find_dev(devlist,2,&dev);
			if(res2 != NULL)
			{
				show_hdlist(res2,showfun_dev_full);
				destroy_dlist(&res2);// 销毁结果链表
			}
			else
				printf("未找到设备\n");
			press_any_key();
			break;
		case 3:// 按类型查找
			printf("请输入设备类型\n");
			scanf("%s",dev.dev_type);
			node_t *res3 = find_dev(devlist,3,&dev);
			if(res3 != NULL)
			{
				show_hdlist(res3,showfun_dev_full);
				destroy_dlist(&res3);// 销毁结果链表

			}
			else
				printf("未找到设备\n");
			press_any_key();
			break;
		case 0:
			return ADMIN_STATE;
		default :
			printf("输入有误，请重试\n");
			press_any_key();
			break;
		}
	}
	return FIND_STATE;
}
